package com.cloudeasy.user.controller.admin;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cloudeasy.api.constant.PermissionConstant;
import com.cloudeasy.api.enums.ResultCodeEnum;
import com.cloudeasy.api.exception.CloudEasyException;
import com.cloudeasy.api.util.ResultUtil;
import com.cloudeasy.api.vo.PageResult;
import com.cloudeasy.api.vo.Result;
import com.cloudeasy.api.vo.user.UserRoleVO;
import com.cloudeasy.core.bean.JwtParser;
import com.cloudeasy.user.dto.UserRoleDTO;
import com.cloudeasy.user.field.UserRoleField;
import com.cloudeasy.user.po.Role;
import com.cloudeasy.user.po.UserRole;
import com.cloudeasy.user.service.RoleService;
import com.cloudeasy.user.service.UserRoleService;
import com.cloudeasy.user.service.expand.VerifyPermissionService;
import com.cloudeasy.user.util.IPageUtil;
import com.cloudeasy.user.util.UserRoleUtil;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@RequestMapping("/user_role")
public class UserRoleController {
    private final VerifyPermissionService verifyPermissionService;

    private final UserRoleService userRoleService;

    private final RoleService roleService;

    private final JwtParser jwtParser;

    public UserRoleController(VerifyPermissionService verifyPermissionService, UserRoleService userRoleService, RoleService roleService, JwtParser jwtParser) {
        this.verifyPermissionService = verifyPermissionService;
        this.userRoleService = userRoleService;
        this.roleService = roleService;
        this.jwtParser = jwtParser;
    }

    /**
     * 获取单个用户的用户角色记录
     *
     * @param userId 用户Id
     * @return {@link List<UserRoleVO>}的{@link Result}
     */
    @GetMapping("/{userId}")
    public Result<List<UserRoleVO>> list(@PathVariable("userId") String userId) {
        List<UserRole> userRoles = userRoleService.listByUserId(userId);

        List<String> roleIdList = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());

        List<Role> roles = roleService.list(roleIdList);
        return ResultUtil.success(UserRoleUtil.convert(userRoles, roles));
    }

    /**
     * 获取用户角色信息
     *
     * @param userIds      用户Id列表
     * @param roleIds      角色Id列表
     * @param operateAreas 管理区域列表
     * @param withSelf     是否管理自己区域
     * @param statuses     状态列表
     * @param asc          正序排序字段
     * @param desc         倒序排序字段
     * @return {@link List<UserRoleVO>}的{@link Result}
     */
    @GetMapping
    public Result<List<UserRoleVO>> list(@RequestParam(value = "userIds", required = false) List<String> userIds,
                                         @RequestParam(value = "roleIds", required = false) List<String> roleIds,
                                         @RequestParam(value = "operateAreas", required = false) List<String> operateAreas,
                                         @RequestParam(value = "withSelf", required = false) Boolean withSelf,
                                         @RequestParam(value = "statuses", required = false) List<Integer> statuses,
                                         @RequestParam(value = "asc", required = false) String[] asc,
                                         @RequestParam(value = "desc", required = false) String[] desc) {
        QueryWrapper<UserRole> queryWrapper = UserRoleUtil.compose(userIds, roleIds, operateAreas, withSelf, statuses, asc, desc);
        List<UserRole> userRoles = userRoleService.list(queryWrapper);

        List<String> roleIdList = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());

        if (roleIdList.size() == 0) {
            return ResultUtil.success();
        }

        List<Role> roles = roleService.list(roleIdList);
        return ResultUtil.success(UserRoleUtil.convert(userRoles, roles));
    }

    /**
     * 分页获取用户角色信息
     *
     * @param userIds      用户Id列表
     * @param roleIds      角色Id列表
     * @param operateAreas 管理区域列表
     * @param withSelf     是否管理自己区域
     * @param statuses     状态列表
     * @param asc          正序排序字段
     * @param desc         倒序排序字段
     * @param page         页数
     * @param size         每页大小
     * @return {@link PageResult<UserRoleVO>}的{@link Result}
     */
    @GetMapping("/{page}/{size}")
    public Result<PageResult<UserRoleVO>> page(@RequestParam(value = "userIds", required = false) List<String> userIds,
                                               @RequestParam(value = "roleIds", required = false) List<String> roleIds,
                                               @RequestParam(value = "operateAreas", required = false) List<String> operateAreas,
                                               @RequestParam(value = "withSelf", required = false) Boolean withSelf,
                                               @RequestParam(value = "statuses", required = false) List<Integer> statuses,
                                               @RequestParam(value = "asc", required = false) String[] asc,
                                               @RequestParam(value = "desc", required = false) String[] desc,
                                               @PathVariable("page") Integer page,
                                               @PathVariable("size") Integer size) {
        QueryWrapper<UserRole> queryWrapper = UserRoleUtil.compose(userIds, roleIds, operateAreas, withSelf, statuses, asc, desc);
        IPage<UserRole> userRoleTempIPage = IPageUtil.compose(page, size);
        IPage<UserRole> userRoleIPage = userRoleService.page(userRoleTempIPage, queryWrapper);

        List<String> roleIdList = new ArrayList<>();

        userRoleIPage.getRecords().forEach(userRole -> roleIdList.add(userRole.getRoleId()));

        if (roleIdList.size() == 0) {
            return ResultUtil.success();
        }

        List<Role> roles = roleService.list(roleIdList);
        return ResultUtil.success(UserRoleUtil.convert(userRoleIPage, roles));
    }

    /**
     * 为用户赋予角色
     *
     * @param authentication {@link Authentication}
     * @param userRoleDTO    {@link UserRoleDTO}
     * @return {@link Result<Boolean>}
     */
    @PostMapping("/{userId}/{roleId}")
    public Result<Boolean> add(Authentication authentication,
                               @PathVariable("userId") String userId,
                               @PathVariable("roleId") String roleId,
                               @RequestBody @Validated UserRoleDTO userRoleDTO) {
        String operateUserId = (String) jwtParser.getOnBody(authentication, "userId");
        if (!verifyPermissionService.canDo(PermissionConstant.ADD_USER_ROLE, Collections.singletonList(userRoleDTO.getOperateArea()), operateUserId)) {
            throw new CloudEasyException(ResultCodeEnum.NO_PERMISSION_OPERATE);
        }
        return ResultUtil.success(userRoleService.save(userId, roleId, userRoleDTO));
    }

    /**
     * 更新用户角色信息
     *
     * @param authentication {@link Authentication}
     * @param userRoleDTO    {@link UserRoleDTO}
     * @return {@link Result<Boolean>}
     */
    @PutMapping("/{userId}/{roleId}")
    public Result<Boolean> update(Authentication authentication,
                                  @PathVariable("userId") String userId,
                                  @PathVariable("roleId") String roleId,
                                  @RequestBody @Validated UserRoleDTO userRoleDTO) {
        UserRole userRole = userRoleService.getByUserIdAndRoleId(userId, roleId);
        if (userRole == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        List<String> targetAreas = new ArrayList<>();
        targetAreas.add(userRole.getOperateArea());
        targetAreas.add(userRoleDTO.getOperateArea());
        String operateUserId = (String) jwtParser.getOnBody(authentication, "userId");
        if (!verifyPermissionService.canDo(PermissionConstant.UPDATE_USER_ROLE, targetAreas, operateUserId)) {
            throw new CloudEasyException(ResultCodeEnum.NO_PERMISSION_OPERATE);
        }

        return ResultUtil.success(userRoleService.updateByUserIdAndRoleId(userId, roleId, userRoleDTO));
    }

    /**
     * 移除用户的角色
     *
     * @param authentication {@link Authentication}
     * @param userId         用户Id
     * @param roleId         角色Id
     * @return {@link Result<Boolean>}
     */
    @DeleteMapping("/{userId}/{roleId}")
    public Result<Boolean> remove(Authentication authentication,
                                  @PathVariable("userId") String userId,
                                  @PathVariable("roleId") String roleId) {
        UserRole userRole = userRoleService.getByUserIdAndRoleId(userId, roleId);
        if (userRole == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        String operateUserId = (String) jwtParser.getOnBody(authentication, "userId");
        if (!verifyPermissionService.canDoByUser(PermissionConstant.DELETE_USER_ROLE, userRole, operateUserId)) {
            throw new CloudEasyException(ResultCodeEnum.NO_PERMISSION_OPERATE);
        }
        return ResultUtil.success(userRoleService.removeByUserIdAndRoleIds(userId, roleId));
    }

}
